﻿using AgencyManagerSystem.Common;
using AgencyManagerSystem.Model;
using Dapper;
using Dapper.Contrib.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace AgencyManagerSystem.DataFetcher
{
    public class ErpFetcher<T> : BaseFetcher<T> where T:ERPModel
    {
        public ErpFetcher()
        {
            TableAttribute tableNameAttribute = typeof(T).GetCustomAttribute<TableAttribute>();
            if (tableNameAttribute != null)
            {
                tableName = tableNameAttribute.Name;
            }
            if (MyHttpContext.Current.Items.ContainsKey(Definer.CURRENT_PROFILE))
                userProfile = MyHttpContext.Current.Items[Definer.CURRENT_PROFILE] as FullUserProfile;
        }
        public override void AddDefaultFilter(StringBuilder stringBuilder, DynamicParameters dynamicParameters)
        {

        }
        public override IList<T> List(IEnumerable<Condition> conditions, int pos, int size, out int count)
        {
            count = 0;
            IList<T> result = null;
            StringBuilder conditionString = new StringBuilder();
            DynamicParameters dynamicParameters = new DynamicParameters();
            if (conditions != null)
            {
                foreach (Condition condition in conditions)
                {
                    StringBuilder orCondition = new StringBuilder(" 1=0 ");
                    foreach (string key in condition.Key.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string keyStr = String.Format("@{0}_{1}", key, COUNTER++);
                        orCondition.AppendFormat(" OR {0} {1} {2} ", key, condition.Op, keyStr);
                        dynamicParameters.Add(keyStr, condition.Value);
                    }
                    conditionString.AppendFormat(" AND ({0})", orCondition);
                }
            }
            string keyColumn = "";
            foreach(var pi in typeof(T).GetProperties())
            {
                if(pi.GetCustomAttribute<KeyAttribute>()!=null)
                {
                    keyColumn = pi.Name;
                    break;
                }
            }
            AddDefaultFilter(conditionString, dynamicParameters);
            string sqlstr = String.Format("WITH _T_ AS ((SELECT TOP {4} ROW_NUMBER() OVER(ORDER BY  {5} DESC) AS _AUTOID_, * FROM {0} WHERE 1 = 1 {1} ))SELECT TOP {3} * FROM _T_ WITH(NOLOCK)  WHERE _AUTOID_ > {2}  ORDER BY _AUTOID_ ", tableName, conditionString, pos, size, pos + size, keyColumn);
            LogHelper.Debug(this.GetType().Name, sqlstr);
            string sqlstrCount = String.Format("SELECT COUNT(*) FROM {0} WITH(NOLOCK) WHERE 1=1 {1} ", tableName, conditionString);
            try
            {
                result = ERPHelper.Query<T>(sqlstr, dynamicParameters).AsList();
                count = ERPHelper.Query<Int32>(sqlstrCount, dynamicParameters).AsList().First();
            }
            catch (Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return result;
        }
        public override IList<T> List(Condition[] conditions=null, int pos=0, int size=1000)
        {
            IList<T> result = null;
            StringBuilder conditionString = new StringBuilder();
            DynamicParameters dynamicParameters = new DynamicParameters();
            if (conditions != null)
            {
                foreach (Condition condition in conditions)
                {
                    StringBuilder orCondition = new StringBuilder(" 1=0 ");
                    foreach (string key in condition.Key.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string keyStr = String.Format("@{0}_{1}", key, COUNTER++);
                        orCondition.AppendFormat(" OR {0} {1} {2} ", key, condition.Op, keyStr);
                        dynamicParameters.Add(keyStr, condition.Value);
                    }
                    conditionString.AppendFormat(" AND ({0})", orCondition);
                }
            }
            string keyColumn = "";
            foreach (var pi in typeof(T).GetProperties())
            {
                if (pi.GetCustomAttribute<KeyAttribute>() != null)
                {
                    keyColumn = pi.Name;
                    break;
                }
            }
            AddDefaultFilter(conditionString, dynamicParameters);
            string sqlstr = String.Format("WITH _T_ AS ((SELECT TOP {4} ROW_NUMBER() OVER(ORDER BY  {5} DESC) AS _AUTOID_, * FROM {0} WHERE 1 = 1 {1} ))SELECT TOP {3} * FROM _T_ WITH(NOLOCK)  WHERE _AUTOID_ > {2}   ORDER BY _AUTOID_ ", tableName, conditionString, pos, size, pos + size, keyColumn);
            LogHelper.Debug(this.GetType().Name, sqlstr);
            try
            {
                result = ERPHelper.Query<T>(sqlstr, dynamicParameters).AsList();
            }
            catch (Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return result;
        }

        public override T Get(int autoid)
        {
            try
            {
                Condition condition = new Condition();
                condition.Key = "AutoId";
                condition.Op = "=";
                condition.Value = autoid;
                IList<T> ls = List(new Condition[] { condition });
                if (ls.Count > 0)
                    return ls.First();
                return null;
            }
            catch (Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return null;
        }
    }
}
